package com.ytf.core.web.application;

import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.ytf.core.common.CacheOperatorApi;
import com.ytf.core.web.pojo.converter.RoleConverter;
import com.ytf.core.web.pojo.dto.RoleDto;
import com.ytf.core.web.pojo.model.Role;
import com.ytf.core.web.pojo.model.RolePermission;
import com.ytf.core.web.pojo.vo.PermissionVo;
import com.ytf.core.web.pojo.vo.RoleVo;
import com.ytf.core.web.service.IPermissionService;
import com.ytf.core.web.service.IRolePermissionService;
import com.ytf.core.web.service.IRoleService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

;

/**
 * @author YTF
 * @className RoleAppService
 * @date 2025/5/20 21:53
 * @description 角色应用层
 */
@Service
public class RoleAppService {

    @Autowired
    private IRoleService iRoleService;
    @Autowired
    private IPermissionService iPermissionService;
    @Autowired
    private PermissionAppService permissionAppService;
    @Autowired
    private IRolePermissionService iRolePermissionService;

    @Resource(name = "roleCache")
    private CacheOperatorApi<RoleVo> roleCache;

    @Transactional(rollbackFor = Exception.class)
    public Boolean insert(RoleDto roleDto) {
        // 1.查询权限是否存在
        List<Long> permissionIds = roleDto.getPermissionIds().stream().map(Long::valueOf).toList();
        Boolean existsByIds = iPermissionService.existsByIds(permissionIds);
        Assert.isTrue(existsByIds, "权限id不存在请重新选择");
        // 2.新增角色
        Role role = RoleConverter.INSTANCE.roleDtoToRole(roleDto);
        boolean save = iRoleService.save(role);
        Assert.isTrue(save, "新增失败");
        // 3.新增角色权限关联
        List<RolePermission> rolePermissionList = permissionIds.stream().map(permissionId -> {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(role.getId());
            rolePermission.setPermissionId(permissionId);
            return rolePermission;
        }).collect(Collectors.toList());
        boolean saveBatch = iRolePermissionService.saveBatch(rolePermissionList);
        Assert.isTrue(saveBatch, "新增角色权限关联失败");
        // 新增角色缓存
        roleCachePut(role);
        return saveBatch;
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long id) {
        // 1.删除角色
        boolean removeById = iRoleService.removeById(id);
        Assert.isTrue(removeById, "删除角色失败");
        // 2.删除角色权限关联
        Boolean aBoolean = iRolePermissionService.removeByRoleId(id);
        Assert.isTrue(aBoolean, "删除角色权限关联失败");
        // 3.删除缓存
        roleCache.remove(String.valueOf(id));
    }

    public RoleVo getById(Long id) {
        RoleVo roleVo = roleCache.get(String.valueOf(id));
        if (roleVo != null) {
            return roleVo;
        }
        Role byId = iRoleService.getById(id);
        return roleCachePut(byId);
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean updateById(Long id, RoleDto roleDto) {
        // 1.查询角色是否存在
        Boolean existsById = iRoleService.existsById(id);
        Assert.isTrue(existsById, "角色id查询不存在");
        Role role = RoleConverter.INSTANCE.roleDtoToRole(roleDto);
        role.setId(id);

        // 2,修改角色
        boolean updateById = iRoleService.updateById(role);
        Assert.isTrue(updateById, "角色修改失败");

        // 3.查询关联权限id列表
        List<Long> existingPermissionIds = iRolePermissionService.listPermissionIdByRoleId(id);

        // 4.计算需要删除和添加的权限
        List<Long> newPermissionIds = roleDto.getPermissionIds().stream().map(Long::valueOf).collect(Collectors.toList());
        Set<Long> commonIds = existingPermissionIds.parallelStream().filter(newPermissionIds::contains).collect(Collectors.toSet());

        existingPermissionIds.removeAll(commonIds);
        newPermissionIds.removeAll(commonIds);

        // 5.执行更新
        if (!existingPermissionIds.isEmpty()) {
            Boolean aBoolean = iRolePermissionService.removeByRoleIdAndPermissionId(role.getId(), existingPermissionIds);
            Assert.isTrue(aBoolean, "删除关联权限失败");
        }

        if (!newPermissionIds.isEmpty()) {
            List<RolePermission> toAdd = newPermissionIds.stream()
                    .map(permissionId -> {
                        RolePermission rolePermission = new RolePermission();
                        rolePermission.setRoleId(role.getId());
                        rolePermission.setPermissionId(permissionId);
                        return rolePermission;
                    })
                    .collect(Collectors.toList());
            boolean saveBatch = iRolePermissionService.saveBatch(toAdd);
            Assert.isTrue(saveBatch, "新增关联权限失败");
        }
        roleCachePut(role);
        return true;
    }

    /**
     * 初始化所有角色
     */
    public void init() {
        System.out.println("角色初始化");
        List<Role> list = iRoleService.list();
        // 新增角色缓存
        list.forEach(this::roleCachePut);
        System.out.println(roleCache.getAllKeyValues());
    }
    private RoleVo roleCachePut(Role role){
        // 2.查询关联权限id列表
        List<Long> permissionIds = iRolePermissionService.listPermissionIdByRoleId(role.getId());
        Assert.notNull(permissionIds, "查询角色没有关联权限");
        // 3.查询权限id列表
        List<PermissionVo> permissionVos = permissionIds.stream().map(i -> permissionAppService.getPermissionById(i)).toList();
        // 4.组装数据
        RoleVo roleVo = RoleConverter.INSTANCE.roleToRoleVo(role);
        roleVo.setPermissionVoList(permissionVos);
        roleCache.put(String.valueOf(role.getId()), roleVo);
        return roleVo;
    }
}
